home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Examples / SpriteTest / SpriteTest.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  46.9 KB  |  1,782 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. // SpriteTest.c
  3. //
  4. // By: Tony Myles
  5. //
  6. // Extensive modifications by Karl Bunker
  7. //
  8. ///--------------------------------------------------------------------------------------
  9. #ifndef __RESOURCES__
  10. #include <Resources.h>
  11. #endif
  12. #ifndef __TOOLUTILS__
  13. #include <ToolUtils.h>
  14. #endif
  15.  
  16. #include <Fonts.h>
  17. #include <TextUtils.h>
  18. #include <Timer.h>
  19. #include <Gestalt.h>
  20. #include <ColorPicker.h>
  21.  
  22. #include <SWIncludes.h>            // Automatically include all SpriteWorld.h files
  23.  
  24. #include <SWGameUtils.h>
  25. #include <SWDitherDown.h>
  26. #include <SWDialogUtils.h>
  27. #include <SWApplication.h>
  28.  
  29. #include "SpriteTest.h"
  30. #include "Application.h"
  31.  
  32. #if __MWERKS__
  33. #include <profiler.h>
  34. #endif
  35.  
  36. #define kBlitterTest         false
  37.  
  38. #define kTicksPerSecond     60.15
  39.  
  40.  
  41. #define kWorldRectInset     0        // modify to test SpriteWorld rect less than window size
  42.  
  43. Boolean            gGlobesVisible;
  44. Boolean            gTitleVisible;
  45. Boolean            gCollisionDetection;
  46. Boolean            gInterlaced;
  47. Boolean            gSkipOddLines;
  48. Boolean            gClearBackground;
  49. Boolean            gColorSprites;
  50.  
  51. ProcType        gWhichSpriteProc;
  52. ProcType        gWhichOffscreenProc;
  53. ProcType        gWhichScreenProc;
  54. CollType        gWhichCollisionProc;
  55. RGBColor        gSpriteColor = { 0x0000, 0x0000, 0xFFFF };    // Default color = blue
  56. short             gMoveDelta;
  57. SpritePtr        gMasterGlobeSprite = NULL;
  58.  
  59. long            gLastTestFrames;
  60. float            gLastTestSeconds;
  61.  
  62. /******************** SetupSWStuff ********************/
  63. OSErr SetupSWStuff(
  64.     SpriteTestPtr* spriteTestP,
  65.     CWindowPtr srcWindowP)
  66. {
  67.     OSErr                 err = noErr;
  68.     SpriteTestPtr         tempSpriteTestP;
  69.     SpriteWorldPtr         spriteWorldP = NULL;
  70.     SpriteLayerPtr         globeSpriteLayerP;
  71.     SpritePtr             globeSpriteArray[kNumberOfGlobeSprites];
  72.     SpritePtr             titleSpriteP;
  73.     SpritePtr             twoSpriteP;
  74.     PixPatHandle         pixPatH = NULL;
  75.     short                 spriteNum;
  76.     short                 oldResRefNum, curResRefNum;
  77.     Rect                 windowRect, worldRect;
  78.  
  79.     
  80.     *spriteTestP = NULL;
  81.  
  82.     SetPort((GrafPtr)srcWindowP);
  83.     
  84.     windowRect = srcWindowP->portRect; 
  85.     worldRect = windowRect;
  86.     InsetRect( &worldRect, kWorldRectInset, kWorldRectInset );
  87.     
  88.     ShowWindow( (WindowPtr)srcWindowP );
  89.     TextFont( systemFont );
  90.     TextSize( 12 );
  91.     MoveTo( 40, 80 );
  92.     DrawString( "\pLoading Sprites... please wait" );
  93.     
  94.     tempSpriteTestP = (SpriteTestPtr)NewPtrClear((Size)sizeof(SpriteTestRec));
  95.     SWSetStickyIfError( MemError() );
  96.     
  97.     {
  98.             // create the sprite world
  99.         (void)SWCreateSpriteWorldFromWindow(&spriteWorldP, srcWindowP, &worldRect, NULL, 0);
  100.     }
  101.  
  102.     if (SWStickyError() == noErr)
  103.     {
  104.         tempSpriteTestP->spriteWorldP = spriteWorldP;
  105.         
  106.             // create the sprite layer
  107.         (void)SWCreateSpriteLayer(&globeSpriteLayerP);
  108.         tempSpriteTestP->globeSpriteLayerP = globeSpriteLayerP;
  109.     }
  110.  
  111.     if (SWStickyError() == noErr)
  112.     {
  113.         oldResRefNum = CurResFile();
  114.         curResRefNum = OpenResFile("\pSpriteTest Frames");
  115.         SWSetStickyIfError( ResError() );
  116.     }
  117.  
  118.     if (SWStickyError() == noErr)
  119.     {
  120.         UseResFile(curResRefNum);
  121.  
  122.         {
  123.             (void)SWCreateSpriteFromSinglePict(
  124.                 spriteWorldP,
  125.                 &gMasterGlobeSprite,
  126.                 NULL,
  127.                 kBaseResID,
  128.                 kBaseResID+1,
  129.                 kGlobeHeight,
  130.                 kGlobeBorderWidth,
  131.                 kFatMask);
  132.  
  133.             if (SWStickyError() == noErr && spriteWorldP->pixelDepth >= 8)
  134.                 (void)SWCreateRLEData( gMasterGlobeSprite );
  135.             
  136.         }
  137.         
  138.         if (SWStickyError() == noErr)
  139.         {
  140.             (void)SWCreateSpriteFromSinglePict(
  141.                 spriteWorldP,
  142.                 &twoSpriteP,
  143.                 NULL,
  144.                 kBaseResID+2,
  145.                 kBaseResID+2,
  146.                 kTwoHeight,
  147.                 kTwoBorderWidth,
  148.                 kFatMask);
  149.             
  150.             if (SWStickyError() == noErr && spriteWorldP->pixelDepth >= 8)
  151.                 (void)SWCreateRLEData( twoSpriteP );
  152.         }
  153.         
  154.         if (SWStickyError() == noErr)
  155.         {
  156.             if ( spriteWorldP->pixelDepth < 8 )
  157.             {
  158.                 DitherDownPict( kBaseResID+2, twoSpriteP->sharedPictGWorld );
  159.                 LowerMaskDepth( kBaseResID+2, twoSpriteP->sharedMaskGWorld );
  160.             }
  161.             SWSetSpriteFrameTime( twoSpriteP, kGlobeSpriteFrameTime*4 );
  162.             SWSetSpriteFrameRange( twoSpriteP, 0, kNumberOfTwoFrames - 1 );
  163.             SWSetSpriteFrameAdvanceMode( twoSpriteP, kSWPatrollingMode );
  164.         }
  165.  
  166.         UseResFile(oldResRefNum);
  167.         CloseResFile(curResRefNum);
  168.     }
  169.  
  170.     if (SWStickyError() == noErr)
  171.     {
  172.         if ( SW_68K && spriteWorldP->pixelDepth >= 8 )
  173.         {
  174.             (void)SWCompileSprite( gMasterGlobeSprite );
  175.         }
  176.     }
  177.     
  178.     if (SWStickyError() == noErr)
  179.     {
  180.             // master globe sprite isn't added to any layer, so we have to lock it separately
  181.         SWLockSprite( gMasterGlobeSprite);
  182.     }
  183.  
  184.     if (SWStickyError() == noErr)
  185.     {
  186.             
  187.         for (spriteNum = 0; spriteNum < kNumberOfGlobeSprites; spriteNum++)
  188.         {
  189.             (void)SWCloneSprite(gMasterGlobeSprite, globeSpriteArray + spriteNum, NULL);
  190.             tempSpriteTestP->globeSpriteArray[spriteNum] = globeSpriteArray[spriteNum];
  191.         }
  192.     
  193.     }
  194.     
  195.     if (SWStickyError() == noErr)
  196.     {
  197.         (void)SWCreateSpriteFromPictResource( 
  198.             spriteWorldP,
  199.             &titleSpriteP, 
  200.             NULL, 
  201.             kBaseResID, 
  202.             kBaseResID, 
  203.             1, 
  204.             kFatMask);
  205.         
  206.         if ( spriteWorldP->pixelDepth < 8 )
  207.         {
  208.             DitherDownPict( kBaseResID, titleSpriteP->frameArray[0]->framePort );
  209.             LowerMaskDepth( kBaseResID, titleSpriteP->frameArray[0]->maskPort );
  210.         }
  211.         else
  212.         {
  213.             if (SWStickyError() == noErr)
  214.                 (void)SWCreateRLEData( titleSpriteP );
  215.         }
  216.         
  217.         tempSpriteTestP->titleSpriteP = titleSpriteP;
  218.         tempSpriteTestP->twoSpriteP = twoSpriteP;
  219.         
  220.         *spriteTestP = tempSpriteTestP;
  221.         
  222.         for (spriteNum = 0; spriteNum < kNumberOfGlobeSprites; spriteNum++)
  223.         {
  224.             if (spriteNum == (kNumberOfGlobeSprites / 2))
  225.             {
  226.                 SWAddSprite(globeSpriteLayerP, titleSpriteP);
  227.                 SWAddSprite(globeSpriteLayerP, twoSpriteP);
  228.             }
  229.             SWAddSprite(globeSpriteLayerP, globeSpriteArray[spriteNum]);
  230.         }
  231.         
  232.  
  233.         SWAddSpriteLayer(spriteWorldP, globeSpriteLayerP);
  234.  
  235.  
  236.         SWLockSpriteWorld(spriteWorldP);
  237.     
  238.         SWSetPortToBackground(spriteWorldP);
  239.         EraseRect( &spriteWorldP->backRect );
  240.         
  241.         if ( spriteWorldP->pixelDepth >= 8 )
  242.         {
  243.             pixPatH = GetPixPat(kBackDropPixPatID);
  244.             if ( pixPatH != NULL )
  245.             {
  246.                 FillCRect(&spriteWorldP->backRect, pixPatH);
  247.                 DisposePixPat(pixPatH);
  248.             }
  249.         }
  250.         else
  251.         {
  252.             FillRect(&spriteWorldP->backRect, &qd.ltGray);
  253.         }
  254.         
  255.         SWSetPortToWindow(spriteWorldP);
  256.         
  257.         SetupSpriteWorldElements(tempSpriteTestP);
  258.     }
  259.     if ( SWStickyError() != noErr)
  260.     {
  261.         DisposeSWStuff(tempSpriteTestP);
  262.     }
  263.  
  264.     return SWStickyError();
  265. }
  266.         
  267.  
  268. /******************** DisposeSWStuff ********************/
  269. void DisposeSWStuff(
  270.     SpriteTestPtr spriteTestP)
  271. {    
  272.     if (spriteTestP != NULL)
  273.     {
  274.         if (spriteTestP->spriteWorldP != NULL)
  275.         {
  276.             SWDisposeSpriteWorld(&spriteTestP->spriteWorldP);
  277.         }
  278.             // gMasterGlobeSprite is not added to any layer, 
  279.             // so SWDisposeSpriteWorld won't dispose of it
  280.         if ( gMasterGlobeSprite != NULL )
  281.         {
  282.             SWDisposeSprite( &gMasterGlobeSprite );
  283.         }
  284.         DisposePtr((Ptr)spriteTestP);
  285.     }
  286. }
  287.  
  288.  
  289. /******************** SetupSpriteWorldElements ********************/
  290. void SetupSpriteWorldElements(
  291.     SpriteTestPtr spriteTestP)
  292. {
  293.     register         long spriteNum;
  294.     Rect             moveBoundsRect;
  295.     Rect            titleDestRect;
  296.     
  297.  
  298.     moveBoundsRect = spriteTestP->spriteWorldP->backRect;
  299.     InsetRect(&moveBoundsRect,-kWorldRectInset,-kWorldRectInset);
  300.     
  301.         // set up the globe sprites
  302.     gMoveDelta = 0;
  303.     for (spriteNum = 0; spriteNum < kNumberOfGlobeSprites; spriteNum++)
  304.     {
  305.         SetupGlobeSprite(spriteTestP->globeSpriteArray[spriteNum], &moveBoundsRect,
  306.                 GetRandom(moveBoundsRect.left, moveBoundsRect.right),
  307.                 GetRandom(moveBoundsRect.top, moveBoundsRect.bottom));
  308.     }
  309.  
  310.         // set up the title sprites
  311.     titleDestRect = spriteTestP->titleSpriteP->destFrameRect;
  312.  
  313.     CenterRect( &titleDestRect, &moveBoundsRect );
  314.     OffsetRect( &titleDestRect, -(kTwoHeight + 2 ), 0 );
  315.     SWSetSpriteLocation(spriteTestP->titleSpriteP, titleDestRect.left, titleDestRect.top );
  316.     
  317.     SWSetSpriteLocation(spriteTestP->twoSpriteP, titleDestRect.right, titleDestRect.top-7 );
  318.     
  319.     SWSetSpriteWorldMaxFPS( spriteTestP->spriteWorldP, 30 );
  320.     SWSetCleanUpSpriteWorld(spriteTestP->spriteWorldP);
  321.  
  322.     gGlobesVisible = true;
  323.     gTitleVisible = true;
  324.     gCollisionDetection = false;
  325.     gWhichCollisionProc = kRLECollisionProc;
  326.     gInterlaced = false;
  327.     gSkipOddLines = kSkipOddLines;
  328.     gClearBackground = false;
  329.     gColorSprites = false;
  330.     
  331.     SetDefaultTestDrawProcs(spriteTestP->spriteWorldP->pixelDepth);
  332.     
  333.     for (spriteNum = 0; spriteNum < kNumberOfGlobeSprites; spriteNum++)
  334.         SWSetSpriteVisible( spriteTestP->globeSpriteArray[spriteNum], gGlobesVisible );
  335.  
  336.     SWSetSpriteVisible( spriteTestP->titleSpriteP, gTitleVisible );
  337.     SWSetSpriteVisible( spriteTestP->twoSpriteP, gTitleVisible );
  338. }
  339.  
  340.  
  341. /******************** SetDefaultTestDrawProcs ********************/
  342.  
  343. void SetDefaultTestDrawProcs( short depth )
  344. {
  345.     gWhichSpriteProc = kCopyBitsProc;
  346.     gWhichOffscreenProc = kCopyBitsProc;
  347.     gWhichScreenProc = kCopyBitsProc;
  348.     
  349.         // Set the default DrawProcs to BlitPixie if possible
  350.     if (depth >= 8 || SW_68K)
  351.     {
  352.         gWhichOffscreenProc = kBlitPixieProc;
  353.         gWhichScreenProc = kBlitPixieProc;
  354.     }
  355.     
  356.     if (depth >= 8)
  357.     {
  358.         if (SW_68K)
  359.             gWhichSpriteProc = kCompiledProc;
  360.         else
  361.             gWhichSpriteProc = kRLEProc;
  362.     }
  363.     else if (SW_68K)
  364.     {
  365.         gWhichSpriteProc = kBlitPixieProc;
  366.     }
  367. }
  368.  
  369.  
  370. /******************** SetupGlobeSprite ********************/
  371.  
  372. void SetupGlobeSprite(
  373.     SpritePtr globeSpriteP,
  374.     Rect *moveBoundsRect,
  375.     short horizLocation,
  376.     short vertLocation)
  377. {
  378.     Rect tempBoundsRect;
  379.     short horizMoveDelta;
  380.     short vertMoveDelta;
  381.     
  382.     gMoveDelta++;
  383.     if ( gMoveDelta > 17 )
  384.         gMoveDelta = 1;
  385.  
  386.     tempBoundsRect = *moveBoundsRect;
  387.  
  388.     horizMoveDelta = GetRandom(2, 6);    // gMoveDelta
  389.     vertMoveDelta =    GetRandom(2, 6);    // gMoveDelta
  390.  
  391.     horizMoveDelta = 1;
  392.     vertMoveDelta =    1;
  393.  
  394.     if (GetRandom(0, 1) == 0)
  395.     {
  396.         horizMoveDelta = -horizMoveDelta;
  397.     }
  398.  
  399.     if (GetRandom(0, 1) == 0)
  400.     {
  401.         vertMoveDelta = -vertMoveDelta;
  402.     }
  403.  
  404.         // set the sprite’s movement characteristics
  405.     SWSetSpriteMoveBounds(globeSpriteP, &tempBoundsRect);
  406.     SWSetSpriteMoveDelta(globeSpriteP, horizMoveDelta, vertMoveDelta);
  407.     SWSetSpriteMoveProc(globeSpriteP, GlobeSpriteMoveProc);
  408.     SWSetSpriteMoveTime(globeSpriteP, kGlobeSpriteMoveTime);
  409.  
  410.     SWSetSpriteFrameTime(globeSpriteP, kGlobeSpriteFrameTime);
  411.     SWSetSpriteFrameRange(globeSpriteP, 0, kNumberOfGlobeFrames - 1);
  412.     SWSetSpriteFrameAdvance(globeSpriteP, GetRandom(0, 1) ? -1 : 1);
  413.  
  414.     SWSetSpriteCollideProc(globeSpriteP, RegionBounceCollideProc);
  415.     SWSetSpriteColor( globeSpriteP, &gSpriteColor );
  416.                         
  417.         // set the sprite’s initial location
  418.     SWSetSpriteLocation(globeSpriteP, horizLocation, vertLocation);
  419. }
  420.  
  421.  
  422. /******************** SpriteTestIdle ********************/
  423. void SpriteTestIdle(
  424.     SpriteTestPtr spriteTestP )
  425. {
  426.     if (gCollisionDetection)
  427.     {
  428.         SWCollideSpriteLayer(spriteTestP->spriteWorldP, 
  429.             spriteTestP->globeSpriteLayerP, spriteTestP->globeSpriteLayerP);
  430.     }
  431.     SWProcessSpriteWorld( spriteTestP->spriteWorldP );
  432.     SWAnimateSpriteWorld( spriteTestP->spriteWorldP );
  433. }
  434.  
  435.  
  436. /******************** UpdateSpriteTest ********************/
  437. void UpdateSpriteTest(
  438.     SpriteTestPtr spriteTestP,
  439.     WindowPtr updateWindowP)
  440. {
  441.     SetPort( updateWindowP );
  442.     if ( updateWindowP->portRect.right - updateWindowP->portRect.left > 
  443.         spriteTestP->spriteWorldP->backRect.right - 
  444.         spriteTestP->spriteWorldP->backRect.left )
  445.     {
  446.         ForeColor( blueColor );
  447.         PaintRect( &updateWindowP->portRect );
  448.     }
  449.     ForeColor( blackColor );
  450.     SWUpdateSpriteWorld(spriteTestP->spriteWorldP, true);
  451. }
  452.  
  453. #pragma mark -
  454.  
  455. /******************** HandleCreateSpriteCommand ********************/
  456. void HandleCreateSpriteCommand(
  457.     SpriteTestPtr spriteTestP)
  458. {
  459.     OSErr err;
  460.     SpritePtr globeSpriteP;
  461.     Rect moveBoundsRect;
  462.     Point mouseLocation;
  463.  
  464.  
  465.     err = SWCloneSprite(gMasterGlobeSprite, &globeSpriteP, NULL);
  466.  
  467.     if (err == noErr)
  468.     {
  469.         moveBoundsRect = spriteTestP->spriteWorldP->backRect;
  470.         GetMouse(&mouseLocation);
  471.         mouseLocation.h -= spriteTestP->spriteWorldP->windRect.left;
  472.         mouseLocation.v -= spriteTestP->spriteWorldP->windRect.top;
  473.         
  474.         SetupGlobeSprite(globeSpriteP, &moveBoundsRect, mouseLocation.h, mouseLocation.v);
  475.  
  476.             // Add sprite in front of or behind the title sprite
  477.         if ( GetRandom(0,1) )
  478.             SWAddSprite(spriteTestP->globeSpriteLayerP, globeSpriteP);
  479.         else
  480.             SWInsertSpriteBeforeSprite(globeSpriteP, spriteTestP->titleSpriteP);
  481.     }
  482. }
  483.  
  484.  
  485. /******************** HandleSpriteTestTitleCommand ********************/
  486. void HandleSpriteTestTitleCommand(
  487.     SpriteTestPtr spriteTestP)
  488. {
  489.     gTitleVisible = !gTitleVisible;
  490.  
  491.     SWSetSpriteVisible(spriteTestP->titleSpriteP, gTitleVisible);
  492.     SWSetSpriteVisible(spriteTestP->twoSpriteP, gTitleVisible);
  493. }
  494.  
  495.  
  496. /******************** HandleBouncingBallsCommand ********************/
  497. void HandleBouncingBallsCommand(
  498.     SpriteTestPtr spriteTestP)
  499. {
  500.     SpritePtr globeSpriteP;
  501.     
  502.     
  503.     gGlobesVisible = !gGlobesVisible;
  504.  
  505.     globeSpriteP = NULL;
  506.     while ((globeSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, globeSpriteP)) != NULL)
  507.     {
  508.         if (globeSpriteP != spriteTestP->titleSpriteP && globeSpriteP != spriteTestP->twoSpriteP)
  509.         {
  510.             SWSetSpriteVisible(globeSpriteP, gGlobesVisible);
  511.         }
  512.     }
  513. }
  514.  
  515.  
  516. /******************** RemoveClickedSprite ********************/
  517. void RemoveClickedSprite(
  518.     SpriteTestPtr spriteTestP)
  519. {
  520.     Point         mouseLocation;
  521.     SpritePtr    spriteToRemove;
  522.     
  523.     
  524.     if ( spriteTestP != NULL )
  525.     {
  526.         GetMouse(&mouseLocation);
  527.         
  528.         mouseLocation.h -= spriteTestP->spriteWorldP->windRect.left;
  529.         mouseLocation.v -= spriteTestP->spriteWorldP->windRect.top;
  530.             // if a sprite has been clicked on, and it isn't the title sprite,
  531.             // then remove it and dispose of it
  532.         spriteToRemove = SWFindSpriteByPoint(spriteTestP->globeSpriteLayerP, NULL, mouseLocation);
  533.         if ( spriteToRemove != NULL &&
  534.             spriteToRemove != spriteTestP->titleSpriteP &&
  535.             spriteToRemove != spriteTestP->twoSpriteP)
  536.         {
  537.             SWRemoveSpriteFromAnimation( spriteTestP->spriteWorldP, spriteToRemove, true );
  538.         }
  539.     }
  540. }
  541.  
  542. #pragma mark -
  543.  
  544. /******************** SetUpTestDialog ********************/
  545. void SetUpTestDialog(
  546.     SpriteTestPtr spriteTestP)
  547. {
  548.     GrafPtr            savePort;
  549.     DialogPtr        theDialog;
  550.     short            itemHit;
  551.     ProcType        originalSpriteProc, 
  552.                     originalOffscreenProc,
  553.                     originalScreenProc;
  554.     Boolean            runNow;
  555.     Boolean            done = false;
  556.     OSErr            err = noErr;
  557.     
  558.  
  559.     GetPort( &savePort );
  560.         
  561.     theDialog = GetNewDialog(kSetUpTestResID, nil, (WindowPtr)-1L);
  562.         
  563.     SetDialogDefaultItem( theDialog, ok );
  564.     SetDialogCancelItem( theDialog, cancel );
  565.     
  566.     originalSpriteProc = gWhichSpriteProc;
  567.     originalOffscreenProc = gWhichOffscreenProc;
  568.     originalScreenProc = gWhichScreenProc;
  569.                 
  570.         // Check if we can do 8-bit-specific tests 
  571. #if !SW_68K
  572.     SetDItemHilite( theDialog, kBlitPixieSpriteButton, 
  573.             (spriteTestP->spriteWorldP->pixelDepth >= 8) );
  574.     SetDItemHilite( theDialog, kBlitPixieOffscreenButton, 
  575.             (spriteTestP->spriteWorldP->pixelDepth >= 8) );
  576.     SetDItemHilite( theDialog, kBlitPixieScreenButton, 
  577.             (spriteTestP->spriteWorldP->pixelDepth >= 8) );
  578. #endif
  579.  
  580.     SetDItemHilite( theDialog, kRLESpriteButton, 
  581.             (spriteTestP->spriteWorldP->pixelDepth >= 8) );
  582.  
  583. #if SW_68K
  584.     SetDItemHilite( theDialog, kCompiledSpriteButton, 
  585.             (spriteTestP->spriteWorldP->pixelDepth >= 8) );
  586. #else
  587.     SetDItemHilite( theDialog, kCompiledSpriteButton, false );
  588. #endif
  589.  
  590.  
  591.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kRunTestNowCheckBox), true );
  592.     
  593.     SetSetUpTestButtons( theDialog );
  594.     
  595.     ShowWindow( theDialog );
  596.     
  597.     while ( !done )
  598.     {    
  599.         ModalDialog( nil, &itemHit );
  600.         switch( itemHit )
  601.         {
  602.             case kCopyBitsSpriteButton:
  603.                 gWhichSpriteProc = kCopyBitsProc;
  604.                 SetSetUpTestButtons( theDialog );
  605.             break;
  606.             case kBlitPixieSpriteButton:
  607.                 gWhichSpriteProc = kBlitPixieProc;
  608.                 SetSetUpTestButtons( theDialog );
  609.             break;
  610.             case kRLESpriteButton:
  611.                 gWhichSpriteProc = kRLEProc;
  612.                 SetSetUpTestButtons( theDialog );
  613.             break;
  614.             case kCompiledSpriteButton:
  615.                 gWhichSpriteProc = kCompiledProc;
  616.                 SetSetUpTestButtons( theDialog );
  617.             break;
  618.             case kCopyBitsOffscreenButton:
  619.                 gWhichOffscreenProc = kCopyBitsProc;
  620.                 SetSetUpTestButtons( theDialog );
  621.             break;
  622.             case kBlitPixieOffscreenButton:
  623.                 gWhichOffscreenProc = kBlitPixieProc;
  624.                 SetSetUpTestButtons( theDialog );
  625.             break;
  626.             case kCopyBitsScreenButton:
  627.                 gWhichScreenProc = kCopyBitsProc;
  628.                 SetSetUpTestButtons( theDialog );
  629.             break;
  630.             case kBlitPixieScreenButton:
  631.                 gWhichScreenProc = kBlitPixieProc;
  632.                 SetSetUpTestButtons( theDialog );
  633.             break;
  634.             case kRunTestNowCheckBox:
  635.                 ToggleDItemValue(theDialog, kRunTestNowCheckBox);
  636.             break;
  637.             case kInterlacedCheckBox:
  638.                 gInterlaced = !gInterlaced;
  639.                 SetSetUpTestButtons( theDialog );
  640.             break;
  641.             case kSkipOddLinesRadioButton:
  642.                 gSkipOddLines = kSkipOddLines;
  643.                 SetSetUpTestButtons( theDialog );
  644.             break;
  645.             case kSkipEvenLinesRadioButton:
  646.                 gSkipOddLines = kSkipEvenLines;
  647.                 SetSetUpTestButtons( theDialog );
  648.             break;
  649.             case kClearBackgroundCheckBox:
  650.                 gClearBackground = !gClearBackground;
  651.                 SetSetUpTestButtons( theDialog );
  652.             break;
  653.             case kColorSpritesCheckBox:
  654.                 gColorSprites = !gColorSprites;
  655.                 SetSetUpTestButtons( theDialog );
  656.             break;
  657.             case kSetClearColorButton:
  658.                 {
  659.                     Point        where = {0,0};
  660.                     StringPtr    prompt = "\pColor to Fill Background with:";
  661.                     RGBColor    newColor = spriteTestP->spriteWorldP->backgroundColor;
  662.                     
  663.                     if ( GetColor( where, prompt, &spriteTestP->spriteWorldP->backgroundColor, &newColor ) )
  664.                     {
  665.                         SWSetBackgroundColor( spriteTestP->spriteWorldP, &newColor );
  666.                     }
  667.                     
  668.                     SWUpdateWindow(spriteTestP->spriteWorldP );
  669.                 }
  670.             break;
  671.             case kSetSpriteColorButton:
  672.                 {
  673.                     Point        where = {0,0};
  674.                     StringPtr    prompt = "\pColor to Fill Sprites with:";
  675.                     SpritePtr    srcSpriteP;
  676.                     
  677.                     if ( GetColor( where, prompt, &gSpriteColor, &gSpriteColor ) )
  678.                     {
  679.                         srcSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, NULL);
  680.                         
  681.                         while (srcSpriteP != NULL)
  682.                         {
  683.                             SWSetSpriteColor( srcSpriteP, &gSpriteColor );
  684.                             srcSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, 
  685.                                     srcSpriteP);
  686.                         }
  687.                     }
  688.                     
  689.                     SWUpdateWindow(spriteTestP->spriteWorldP );
  690.                 }
  691.             break;
  692.             case ok:
  693.                 runNow = GetControlValue( (ControlHandle)GetDItemHandle(theDialog, kRunTestNowCheckBox));
  694.             case cancel:
  695.                 done = true;
  696.             break;
  697.         }
  698.     }
  699.     DisposeDialog( theDialog );
  700.     SetPort( savePort );
  701.     
  702.     if ( itemHit == ok )
  703.     {
  704.         if ( runNow )
  705.         {
  706.             SWSetPortToWindow( spriteTestP->spriteWorldP );
  707.             RunTheTest( spriteTestP );
  708.             
  709.             DisplayPerformance(gLastTestFrames, gLastTestSeconds);
  710.         }
  711.     }
  712.     if ( itemHit == cancel )
  713.     {
  714.         gWhichSpriteProc = originalSpriteProc;
  715.         gWhichOffscreenProc = originalOffscreenProc;
  716.         gWhichScreenProc = originalScreenProc;
  717.     }
  718. }
  719.  
  720.  
  721.  
  722. /******************** SetSetUpTestButtons ********************/
  723. void SetSetUpTestButtons(
  724.     DialogPtr theDialog)
  725. {
  726.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kCopyBitsSpriteButton), 
  727.         (gWhichSpriteProc == kCopyBitsProc) );
  728.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kBlitPixieSpriteButton), 
  729.         (gWhichSpriteProc == kBlitPixieProc) );
  730.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kRLESpriteButton), 
  731.         (gWhichSpriteProc == kRLEProc) );
  732.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kCompiledSpriteButton), 
  733.         (gWhichSpriteProc == kCompiledProc) );
  734.     
  735.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kCopyBitsOffscreenButton), 
  736.         (gWhichOffscreenProc == kCopyBitsProc) );
  737.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kBlitPixieOffscreenButton), 
  738.         (gWhichOffscreenProc == kBlitPixieProc) );
  739.     
  740.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kCopyBitsScreenButton), 
  741.         (gWhichScreenProc == kCopyBitsProc) );
  742.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kBlitPixieScreenButton), 
  743.         (gWhichScreenProc == kBlitPixieProc) );
  744.  
  745.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kInterlacedCheckBox), 
  746.          gInterlaced );
  747.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kSkipOddLinesRadioButton), 
  748.         (gSkipOddLines == kSkipOddLines) );
  749.     SetDItemHilite( theDialog, kSkipOddLinesRadioButton, gInterlaced );
  750.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kSkipEvenLinesRadioButton), 
  751.         (gSkipOddLines == kSkipEvenLines) );
  752.     SetDItemHilite( theDialog, kSkipEvenLinesRadioButton, gInterlaced );
  753.  
  754.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kClearBackgroundCheckBox), 
  755.          gClearBackground );
  756.     SetDItemHilite( theDialog, kSetClearColorButton, gClearBackground );
  757.  
  758.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kColorSpritesCheckBox), 
  759.          gColorSprites );
  760.     SetDItemHilite( theDialog, kSetSpriteColorButton, gColorSprites );
  761. }
  762.  
  763. /******************** CollisionProcDialog ********************/
  764.  
  765. void CollisionProcDialog(
  766.     SpriteTestPtr spriteTestP)
  767. {
  768.     Boolean            originalCollisionOn = gCollisionDetection;
  769.     CollType        originalCollisionType = gWhichCollisionProc;
  770.     GrafPtr            savePort;
  771.     DialogPtr        theDialog;
  772.     Boolean            done = false;
  773.     short            itemHit;
  774.     
  775.     GetPort( &savePort );
  776.         
  777.     theDialog = GetNewDialog(kCollisionProcResID, nil, (WindowPtr)-1L);
  778.     if ( theDialog == NULL )
  779.         return;
  780.         
  781.     SetDialogDefaultItem( theDialog, ok );
  782.     SetDialogCancelItem( theDialog, cancel );
  783.     
  784.     SetCollisionProcButtons( theDialog );
  785.  
  786.     SetDItemHilite( theDialog, kPixelCollisionButton, 
  787.         (spriteTestP->spriteWorldP->pixelDepth >= 8) );    
  788.     SetDItemHilite( theDialog, kRLECollisionButton, 
  789.         (spriteTestP->spriteWorldP->pixelDepth >= 8) );
  790.     
  791.     ShowWindow( theDialog );
  792.     
  793.     while ( !done )
  794.     {    
  795.         ModalDialog( nil, &itemHit );
  796.         
  797.         switch ( itemHit )
  798.         {
  799.             case ok:
  800.             case cancel:
  801.                 done = true;
  802.                 break;
  803.             case kCollisionDetectionCheckbox:
  804.                 gCollisionDetection = !gCollisionDetection;
  805.                 SetCollisionProcButtons( theDialog );
  806.                 break;
  807.             case kRectCollisionButton:
  808.                 gWhichCollisionProc = kRectCollisionProc;
  809.                 SetCollisionProcButtons( theDialog );
  810.                 break;
  811.             case kRadiusCollisionButton:
  812.                 gWhichCollisionProc = kRadiusCollisionProc;
  813.                 SetCollisionProcButtons( theDialog );
  814.                 break;
  815.             case kPixelCollisionButton:
  816.                 gWhichCollisionProc = kPixelCollisionProc;
  817.                 SetCollisionProcButtons( theDialog );
  818.                 break;
  819.             case kRegionCollisionButton:
  820.                 gWhichCollisionProc = kRegionCollisionProc;
  821.                 SetCollisionProcButtons( theDialog );
  822.                 break;
  823.             case kRLECollisionButton:
  824.                 gWhichCollisionProc = kRLECollisionProc;
  825.                 SetCollisionProcButtons( theDialog );
  826.                 break;
  827.         }
  828.     }
  829.     
  830.     if ( itemHit == cancel )
  831.     {
  832.         gCollisionDetection = originalCollisionOn;
  833.         gWhichCollisionProc = originalCollisionType;
  834.     }
  835.  
  836.     DisposeDialog( theDialog );
  837.     SetPort( savePort );
  838.  
  839. }
  840.  
  841. void SetCollisionProcButtons( DialogPtr theDialog )
  842. {
  843.     SetControlValue( (ControlHandle) GetDItemHandle(theDialog, kCollisionDetectionCheckbox),
  844.         gCollisionDetection );
  845.                 
  846.     SetControlValue( (ControlHandle) GetDItemHandle(theDialog, kRectCollisionButton),
  847.         gWhichCollisionProc ==  kRectCollisionProc);
  848.     SetControlValue( (ControlHandle) GetDItemHandle(theDialog, kRadiusCollisionButton),
  849.         gWhichCollisionProc ==  kRadiusCollisionProc);
  850.     SetControlValue( (ControlHandle) GetDItemHandle(theDialog, kPixelCollisionButton),
  851.         gWhichCollisionProc ==  kPixelCollisionProc);
  852.     SetControlValue( (ControlHandle) GetDItemHandle(theDialog, kRegionCollisionButton),
  853.         gWhichCollisionProc ==  kRegionCollisionProc);
  854.     SetControlValue( (ControlHandle) GetDItemHandle(theDialog, kRLECollisionButton),
  855.         gWhichCollisionProc ==  kRLECollisionProc);
  856.     
  857. }
  858.  
  859. /******************** RunAllTests ********************/
  860.  
  861. extern WindowPtr    gWindowP;    // in Application.c
  862.  
  863. void RunAllTests(
  864.     SpriteTestPtr spriteTestP)
  865. {
  866.     StringPtr    reportFileName = "\pSpriteTest "
  867.                                         #if SW_68K
  868.                                                 "68K"
  869.                                         #else
  870.                                                 "PPC"
  871.                                         #endif
  872.                                                         " FPS Report";
  873.     
  874.     StringPtr    reportTitle = "\p \015\015\015\015"  // <-- Make room for header image (\015 is \r, even in MPW)
  875.                               "SpriteTest results:\015"
  876.                               "(should be viewed with a huge tab size in e.g. BBEdit,"
  877.                               " or imported into a spreadsheet)\015"
  878.                               "\015";
  879.  
  880.     StringPtr    drawProcNames[4] =
  881.                 {    "\pCopyBits", "\pBlitPixie", "\pRLE", "\pCompiled"  }; 
  882.  
  883.     short        depth;
  884.     OSErr        err;
  885.     float        fps;
  886.     short        ref;
  887.     StringPtr    str;
  888.     Str255        numStr;
  889.     Ptr            buffer;
  890.     long        count;
  891.     UInt32        tick,startTick;
  892.     long        result;
  893.     Handle        pict,oldres;
  894.     FInfo        info;
  895.     GDHandle    windowGDH;
  896.     Rect        globalRect;
  897.     DialogPtr    dialog = NULL;
  898.     Handle        snd;
  899.     
  900.     err = GetFInfo( reportFileName, 0, &info );
  901.     if ( err == fnfErr )
  902.     {
  903.         err = Create( reportFileName, 0, 'ttxt', 'TEXT' );
  904.     }
  905.  
  906.         // add header picture
  907.     if ( err == noErr )
  908.     {
  909.         CreateResFile( reportFileName );
  910.         err = ResError();
  911.         
  912.         if ( err == noErr || err == dupFNErr )
  913.         {
  914.             ref = OpenResFile( reportFileName );
  915.             if ( ref != -1 )
  916.             {
  917.                 UseResFile(ref);
  918.                 
  919.                 pict = GetResource( 'PICT', 130 );
  920.                 if ( pict != NULL )
  921.                 {
  922.                     DetachResource( pict );
  923.                     if ( ResError() == noErr )
  924.                     {
  925.                         oldres = Get1Resource( 'PICT', 1000 );
  926.                         if ( oldres != NULL )
  927.                             RemoveResource( oldres);
  928.                             
  929.                         AddResource( pict, 'PICT', 1000, "\p" );
  930.                     }
  931.                     CloseResFile( ref );
  932.                 }
  933.             }
  934.             err = noErr;
  935.         }
  936.     }
  937.     
  938.     #define WRITE_STRING(string)    \
  939.         str = string;    \
  940.         count = str[0];    \
  941.         buffer = (Ptr) (str + 1);    \
  942.         err = FSWrite( ref, &count, buffer )
  943.  
  944.     if ( err == noErr )
  945.         err = FSOpen( reportFileName, 0, &ref );
  946.     
  947.     if ( err == noErr )
  948.     {
  949.         SetEOF( ref, 0 );
  950.         
  951.         WRITE_STRING(reportTitle);
  952.         
  953.         WRITE_STRING("\pTest ran on:\t");
  954.         GetDateTime(&startTick);
  955.         IUDateString(startTick,longDate,numStr);
  956.         WRITE_STRING(numStr);
  957.         WRITE_STRING("\p ");
  958.         IUTimeString(startTick,longDate,numStr);
  959.         WRITE_STRING(numStr);
  960.         WRITE_STRING("\p\015");
  961.     
  962.     #if SW_68K
  963.         WRITE_STRING("\pRunning:\t680X0 code\015");
  964.     #else
  965.         WRITE_STRING("\pRunning:\tPowerPC code\015");
  966.     #endif
  967.  
  968.         Gestalt( gestaltSystemVersion, &result );
  969.         WRITE_STRING("\pSystem Version ID:\t");
  970.         NumToString(result,numStr);
  971.         WRITE_STRING(numStr);
  972.         WRITE_STRING("\p\015");
  973.     
  974.         result = HiWord( SWGetSpriteWorldVersion() );
  975.         WRITE_STRING("\pSpriteWorld Version ID:\t");
  976.         NumToString(result,numStr);
  977.         WRITE_STRING(numStr);
  978.         WRITE_STRING("\p\015");
  979.     
  980.         Gestalt( gestaltMachineType, &result );
  981.         WRITE_STRING("\pMachine Gestalt ID:\t");
  982.         NumToString(result,numStr);
  983.         WRITE_STRING(numStr);
  984.         WRITE_STRING("\p\015");
  985.     
  986.         Gestalt( gestaltNativeCPUtype, &result );
  987.         WRITE_STRING("\pNative CPU ID:\t");
  988.         NumToString(result,numStr);
  989.         WRITE_STRING(numStr);
  990.         WRITE_STRING("\p\015");
  991.         
  992.         Gestalt( gestaltPhysicalRAMSize, &result );
  993.         WRITE_STRING("\pPhysical RAM Size:\t");
  994.         NumToString((result / 1024) / 1024,numStr);
  995.         WRITE_STRING(numStr);
  996.         WRITE_STRING("\p MB\015");
  997.         
  998.         Gestalt( gestaltVMAttr, &result );
  999.         if ( result & ( 1 << gestaltVMPresent ) )
  1000.         {
  1001.             WRITE_STRING("\pVirtual Memory:\tOn\015");
  1002.         
  1003.             Gestalt( gestaltLogicalRAMSize, &result );
  1004.             
  1005.             WRITE_STRING("\pVirtual RAM Size:\t");
  1006.             NumToString(result / (1024L * 1024L),numStr);
  1007.             WRITE_STRING(numStr);
  1008.             WRITE_STRING("\p MB\015");
  1009.         }
  1010.         else
  1011.         {
  1012.             WRITE_STRING("\pVirtual Memory:\tOff\015");
  1013.         }
  1014.         
  1015.         globalRect = gWindowP->portRect;
  1016.         SetPort(gWindowP);
  1017.         LocalToGlobal( &topLeft(globalRect) );
  1018.         LocalToGlobal( &botRight(globalRect) );
  1019.         windowGDH = GetMaxDevice( &globalRect );
  1020.         
  1021.         WRITE_STRING("\pCurrent Screen Resolution:\t");
  1022.         if (windowGDH)
  1023.         {
  1024.             NumToString( (**windowGDH).gdRect.right - (**windowGDH).gdRect.left,numStr);
  1025.             WRITE_STRING(numStr);
  1026.             WRITE_STRING("\px");
  1027.             NumToString( (**windowGDH).gdRect.bottom - (**windowGDH).gdRect.top,numStr);
  1028.             WRITE_STRING(numStr);
  1029.             WRITE_STRING("\p pixels\015");
  1030.         }
  1031.         else
  1032.         {
  1033.             WRITE_STRING("\p unknown ?\015");
  1034.         }
  1035.         
  1036.         WRITE_STRING("\p\015");
  1037.         
  1038.             // flush buffer to disk, just in case something ugly happens...
  1039.         {
  1040.             IOParam        param;
  1041.             long        pos;
  1042.             
  1043.             GetFPos(ref,&pos);
  1044.             SetEOF(ref,pos);
  1045.             
  1046.             param.ioCompletion = NULL;
  1047.             param.ioNamePtr = NULL;
  1048.             param.ioRefNum = ref;
  1049.             
  1050.             err = PBFlushFileSync( (ParmBlkPtr) ¶m );
  1051.             FlushVol(NULL,0);
  1052.         }
  1053.         
  1054.         WRITE_STRING("\pDepth\tScreenProc\tOffscreenProc\tSpriteProc\tFPS\015");
  1055.     
  1056.         for ( depth = 1; depth <= 32; depth *= 2 )
  1057.         {
  1058.             SWSetPortToWindow( spriteTestP->spriteWorldP );
  1059.             err = SetNewMonitorDepth( depth );
  1060.             
  1061.             if ( err == noErr )
  1062.             {
  1063.                 SWSetPortToWindow( spriteTestP->spriteWorldP );
  1064.             
  1065.                 for ( gWhichScreenProc = kCopyBitsProc; gWhichScreenProc <= kBlitPixieProc; gWhichScreenProc++ )
  1066.                 {
  1067.                         // no AllBit blitters on PPC
  1068.                     if ( SW_PPC && (depth) < 8 && (gWhichScreenProc == kBlitPixieProc) )
  1069.                         continue;    
  1070.                         
  1071.                     for ( gWhichOffscreenProc = kCopyBitsProc; gWhichOffscreenProc <= kBlitPixieProc; gWhichOffscreenProc++ )
  1072.                     {
  1073.                             // no AllBit blitters on PPC
  1074.                         if ( SW_PPC && (depth < 8) && (gWhichOffscreenProc == kBlitPixieProc) )
  1075.                             continue;    
  1076.                         
  1077.                         for ( gWhichSpriteProc = kCopyBitsProc; gWhichSpriteProc <= kCompiledProc; gWhichSpriteProc++ )
  1078.                         {
  1079.                                 // no AllBit blitters on PPC
  1080.                             if ( SW_PPC && (depth < 8) && (gWhichScreenProc == kBlitPixieProc) )
  1081.                                 continue;    
  1082.                                 // no RLE or compiled blitters below 256 colors
  1083.                             if ( depth < 8 && (gWhichSpriteProc == kRLEProc || gWhichSpriteProc == kCompiledProc) )
  1084.                                 continue;
  1085.                                 // compiled sprites are 68k-only
  1086.                             if ( SW_PPC && (gWhichSpriteProc == kCompiledProc))
  1087.                                 continue;
  1088.                             
  1089.                             NumToString(depth,numStr);
  1090.                             ParamText(
  1091.                                 numStr,
  1092.                                 drawProcNames[gWhichScreenProc],
  1093.                                 drawProcNames[gWhichOffscreenProc],
  1094.                                 drawProcNames[gWhichSpriteProc]);
  1095.                             
  1096.                             dialog = GetNewDialog( 201, NULL, (WindowPtr) -1 );
  1097.                             if ( dialog != NULL)
  1098.                             {
  1099.                                 DrawDialog(dialog);
  1100.                                 tick = TickCount();
  1101.                                 
  1102.                                     // wait 3 seconds, so user can read
  1103.                                 while ( TickCount() < tick + 3 * 60 )
  1104.                                 {
  1105.                                     if ( Button() )
  1106.                                         goto abort;        // yes, goto.  Flags are silly. :) // afb
  1107.                                 }
  1108.                                 
  1109.                                 DisposeDialog(dialog);
  1110.                                 dialog = NULL;
  1111.                             }
  1112.                             SWSetPortToWindow( spriteTestP->spriteWorldP );
  1113.                             RunTheTest( spriteTestP );
  1114.                             
  1115.                             if ( Button() )
  1116.                                 goto abort;
  1117.                                 
  1118.                             fps = (gLastTestSeconds > 0.0) ? (float) gLastTestFrames / gLastTestSeconds : gLastTestFrames;
  1119.  
  1120.                             NumToString(depth,numStr);
  1121.                             WRITE_STRING(numStr);
  1122.                             WRITE_STRING("\p\t");
  1123.                             
  1124.                             WRITE_STRING(drawProcNames[gWhichScreenProc]);
  1125.                             WRITE_STRING("\p\t");
  1126.                             
  1127.                             WRITE_STRING(drawProcNames[gWhichOffscreenProc]);
  1128.                             WRITE_STRING("\p\t");
  1129.                             
  1130.                             WRITE_STRING(drawProcNames[gWhichSpriteProc]);
  1131.                             WRITE_STRING("\p\t");
  1132.                             
  1133.                             NumToString(fps,numStr);
  1134.                             WRITE_STRING(numStr);
  1135.                             WRITE_STRING("\p\015");
  1136.                             
  1137.                         }
  1138.                     }
  1139.                 }
  1140.             }
  1141.         }
  1142.     
  1143.         WRITE_STRING("\p\015Test completed on:\t");
  1144.         GetDateTime(&tick);
  1145.         IUDateString(tick,longDate,numStr);
  1146.         WRITE_STRING(numStr);
  1147.         WRITE_STRING("\p ");
  1148.         IUTimeString(tick,longDate,numStr);
  1149.         WRITE_STRING(numStr);
  1150.         WRITE_STRING("\p\015");
  1151.  
  1152.         WRITE_STRING("\pRunning time:\t");
  1153.         NumToString( (tick - startTick) / 60,numStr);
  1154.         WRITE_STRING(numStr);
  1155.         WRITE_STRING("\p minutes\015");                
  1156.  
  1157.         // Done! <yoohoo>
  1158.         
  1159.         snd = GetResource('snd ',128);
  1160.         if ( snd != NULL )
  1161.             SndPlay( NULL, (SndListHandle) snd, false );
  1162.         else
  1163.             SysBeep(1);
  1164.             
  1165.     abort:
  1166.     
  1167.         if ( dialog != NULL )
  1168.         {
  1169.             DisposeDialog( dialog );
  1170.             dialog = NULL;
  1171.         }
  1172.         
  1173.         err = FSClose( ref );
  1174.     
  1175.     }
  1176.  
  1177. }
  1178.  
  1179.  
  1180. /******************** RunTheTest ********************/
  1181. void RunTheTest(
  1182.     SpriteTestPtr spriteTestP)
  1183. {
  1184.     WindowPtr         testWindowP = FrontWindow();
  1185.     SpritePtr         curSpriteP;
  1186.     unsigned long     frames, seconds;
  1187.     long             ticks;
  1188.     Rect            shieldRect;
  1189.     Point            shieldRectOffset;
  1190.     Rect            srcRect,
  1191.                     destRect;
  1192.     UnsignedWide    startMicroseconds,
  1193.                     endMicroseconds;
  1194.  
  1195.         // set up for the test
  1196.     shieldRect = spriteTestP->spriteWorldP->windowFrameP->frameRect;
  1197.     SWSetPortToWindow(spriteTestP->spriteWorldP);
  1198.     LocalToGlobal( &topLeft(shieldRect) );
  1199.     LocalToGlobal( &botRight(shieldRect) );
  1200.     shieldRectOffset.h = shieldRectOffset.v = 0;
  1201.     ShieldCursor( &shieldRect, shieldRectOffset );
  1202.     
  1203.     SWHideMenuBar(testWindowP);
  1204.     
  1205.     UpdateSpriteTest( spriteTestP, testWindowP );
  1206.     
  1207.     curSpriteP = NULL;
  1208.     while ((curSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, curSpriteP)) != NULL)
  1209.     {
  1210.         if (curSpriteP != spriteTestP->titleSpriteP && curSpriteP != spriteTestP->twoSpriteP)
  1211.         {
  1212.             SWSetSpriteFrameTime(curSpriteP, 0);
  1213.             SWSetSpriteMoveTime(curSpriteP, 0);
  1214.             
  1215.             if ( gColorSprites )
  1216.             {
  1217.                 if ( spriteTestP->spriteWorldP->pixelDepth < 8 )
  1218.                 {
  1219.                     (void)SWSetSpriteDrawProc(curSpriteP, SWStdSpriteColorDrawProc);
  1220.                 }
  1221.                 else
  1222.                 {
  1223.                     switch ( gWhichSpriteProc )
  1224.                     {
  1225.                         case kCopyBitsProc:
  1226.                             (void)SWSetSpriteDrawProc(curSpriteP, SWStdSpriteColorDrawProc);
  1227.                             break;
  1228.                         case kBlitPixieProc:
  1229.                         case kCompiledProc:
  1230.                             (void)SWSetSpriteDrawProc(curSpriteP, BlitPixieMaskColorDrawProc);
  1231.                             break;
  1232.                         case kRLEProc:
  1233.                             (void)SWSetSpriteDrawProc(curSpriteP, BlitPixieRLEColorDrawProc);
  1234.                             break;
  1235.                     }
  1236.                 }
  1237.             }
  1238.             else
  1239.             {
  1240.                 if ( spriteTestP->spriteWorldP->pixelDepth < 8 )
  1241.                 {
  1242.                     if ( SW_68K && (gWhichSpriteProc == kBlitPixieProc || gWhichSpriteProc == kCompiledProc) )
  1243.                         (void)SWSetSpriteDrawProc(curSpriteP, BlitPixieAllBitMaskDrawProc);
  1244.                     else
  1245.                         (void)SWSetSpriteDrawProc(curSpriteP, SWStdSpriteDrawProc);
  1246.                 }
  1247.                 else
  1248.                 {
  1249.                     switch ( gWhichSpriteProc )
  1250.                     {
  1251.                         case kBlitPixieProc:
  1252.                             (void)SWSetSpriteDrawProc(curSpriteP, BlitPixieMaskDrawProc);
  1253.                             break;
  1254.                         case kRLEProc:
  1255.                             (void)SWSetSpriteDrawProc(curSpriteP, BlitPixieRLEDrawProc);
  1256.                             break;
  1257.                         case kCompiledProc:
  1258.                             (void)SWSetSpriteDrawProc(curSpriteP, BlitPixieCompiledSpriteDrawProc);
  1259.                             break;
  1260.                     }
  1261.                 }
  1262.             }
  1263.             
  1264.             if ( gCollisionDetection )
  1265.             {
  1266.                 switch ( gWhichCollisionProc )
  1267.                 {
  1268.                     case kRectCollisionProc:
  1269.                         (void)SWSetSpriteCollideProc(curSpriteP, RectBounceCollideProc);
  1270.                         break;
  1271.                     case kRadiusCollisionProc:
  1272.                         (void)SWSetSpriteCollideProc(curSpriteP, RadiusBounceCollideProc);
  1273.                         break;
  1274.                     case kPixelCollisionProc:
  1275.                         if ( spriteTestP->spriteWorldP->pixelDepth >= 8 )
  1276.                             (void)SWSetSpriteCollideProc(curSpriteP, PixelBounceCollideProc);
  1277.                         else
  1278.                             (void)SWSetSpriteCollideProc(curSpriteP, RegionBounceCollideProc);
  1279.                         break;
  1280.                     case kRegionCollisionProc:
  1281.                         (void)SWSetSpriteCollideProc(curSpriteP, RegionBounceCollideProc);
  1282.                         break;
  1283.                     case kRLECollisionProc:
  1284.                         if ( spriteTestP->spriteWorldP->pixelDepth >= 8 )
  1285.                             (void)SWSetSpriteCollideProc(curSpriteP, RLEBounceCollideProc);
  1286.                         else
  1287.                             (void)SWSetSpriteCollideProc(curSpriteP, RegionBounceCollideProc);
  1288.                         break;
  1289.                 }
  1290.             }
  1291.         }
  1292.     }
  1293.     
  1294.     if ( gWhichSpriteProc == kBlitPixieProc || gWhichSpriteProc == kCompiledProc || gWhichSpriteProc == kRLEProc )
  1295.     {
  1296.         if ( spriteTestP->spriteWorldP->pixelDepth >= 8 )
  1297.         {
  1298.             (void)SWSetSpriteDrawProc(spriteTestP->titleSpriteP, BlitPixieMaskDrawProc);
  1299.             (void)SWSetSpriteDrawProc(spriteTestP->twoSpriteP, BlitPixieMaskDrawProc);
  1300.         }
  1301.         else if (SW_68K)
  1302.         {
  1303.             (void)SWSetSpriteDrawProc(spriteTestP->titleSpriteP, BlitPixieAllBitMaskDrawProc);
  1304.             (void)SWSetSpriteDrawProc(spriteTestP->twoSpriteP, BlitPixieAllBitMaskDrawProc);    
  1305.         }
  1306.     }
  1307.     if ( gWhichOffscreenProc == kBlitPixieProc )
  1308.     {
  1309.         if ( spriteTestP->spriteWorldP->pixelDepth >= 8 )
  1310.         {
  1311.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  1312.                 BlitPixieRectDrawProc);
  1313.         }
  1314.         else if (SW_68K)
  1315.         {
  1316.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  1317.                 BlitPixieAllBitRectDrawProc);    
  1318.         }
  1319.     }
  1320.     if ( gWhichScreenProc == kBlitPixieProc )
  1321.     {
  1322.         if ( spriteTestP->spriteWorldP->pixelDepth >= 8 )
  1323.         {
  1324.             (void)SWSetSpriteWorldScreenDrawProc(spriteTestP->spriteWorldP, 
  1325.                 BlitPixieRectDrawProc);
  1326.         }
  1327.         else if (SW_68K)
  1328.         {
  1329.             (void)SWSetSpriteWorldScreenDrawProc(spriteTestP->spriteWorldP, 
  1330.                 BlitPixieAllBitRectDrawProc);
  1331.         }
  1332.     }
  1333.  
  1334.     SWSetFrameInterlacingMode( spriteTestP->spriteWorldP->workFrameP, gInterlaced, gSkipOddLines );
  1335.     SWSetFrameInterlacingMode( spriteTestP->spriteWorldP->windowFrameP, gInterlaced, gSkipOddLines );
  1336.  
  1337.     if ( gInterlaced )
  1338.     {
  1339.         if ( gWhichOffscreenProc == kCopyBitsProc )
  1340.         {
  1341.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  1342.                 SWInterlacedCopyBitsDrawProc);
  1343.         }
  1344.         if ( gWhichScreenProc == kCopyBitsProc )
  1345.         {
  1346.             (void)SWSetSpriteWorldScreenDrawProc(spriteTestP->spriteWorldP, 
  1347.                 SWInterlacedCopyBitsDrawProc);
  1348.         }
  1349.         
  1350.             // paint window black, since we're only drawing every other scanline
  1351.         SWSetPortToWindow( spriteTestP->spriteWorldP );
  1352.         PaintRect( &spriteTestP->spriteWorldP->windowFrameP->frameRect );
  1353.     
  1354.         SWUpdateSpriteWorld( spriteTestP->spriteWorldP, true );
  1355.     }
  1356.  
  1357.     if ( gClearBackground )
  1358.     {
  1359.         if (    gWhichOffscreenProc == kBlitPixieProc &&
  1360.                 spriteTestP->spriteWorldP->pixelDepth >= 8 )
  1361.         {
  1362.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  1363.                 BlitPixieClearDrawProc);
  1364.         }
  1365.         else if ( gWhichOffscreenProc == kCopyBitsProc ||
  1366.                 spriteTestP->spriteWorldP->pixelDepth < 8  )
  1367.         {
  1368.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  1369.                 SWStdWorldClearDrawProc);
  1370.         }
  1371.         
  1372.         SWUpdateSpriteWorld( spriteTestP->spriteWorldP, true );
  1373.     }
  1374.         
  1375.         // Floor it!!!
  1376.     SWSetSpriteWorldMaxFPS( spriteTestP->spriteWorldP, 0 );
  1377.     
  1378.     ticks = TickCount();
  1379.  
  1380.  
  1381.         // the actual tests...
  1382.         
  1383.         // a straight blitter test -- no animation to screen
  1384.  
  1385.     if ( kBlitterTest )
  1386.     {
  1387.         srcRect = gMasterGlobeSprite->frameArray[0]->frameRect;
  1388.         destRect = srcRect;
  1389.         OffsetRect( &destRect, 3, 0 );
  1390.         Microseconds( &startMicroseconds );
  1391.         
  1392.         if ( spriteTestP->spriteWorldP->pixelDepth >= 8 )
  1393.         {
  1394.             for (frames = 0; frames < 10000; frames++ )
  1395.             {
  1396.                 BlitPixieMaskDrawProc(
  1397.                     gMasterGlobeSprite->frameArray[0],
  1398.                     spriteTestP->spriteWorldP->workFrameP,
  1399.                     &srcRect,
  1400.                     &destRect);
  1401.             }
  1402.         }
  1403.     #if SW_68K
  1404.         else
  1405.         {
  1406.             for (frames = 0; frames < 10000; frames++ )
  1407.             {
  1408.                 BlitPixieAllBitMaskDrawProc(
  1409.                     gMasterGlobeSprite->frameArray[0],
  1410.                     spriteTestP->spriteWorldP->workFrameP,
  1411.                     &srcRect,
  1412.                     &destRect);
  1413.             }
  1414.         }
  1415.     #endif
  1416.         
  1417.         Microseconds( &endMicroseconds );
  1418.         seconds = endMicroseconds.lo - startMicroseconds.lo;
  1419.         if ( endMicroseconds.hi != startMicroseconds.hi )
  1420.             seconds = 0;        // do test over
  1421.     }
  1422.     else    // a test of animation to screen
  1423.     {
  1424. /*
  1425.         ProfilerSetStatus( true );
  1426. */
  1427.         for (frames = 0; ((TickCount() - ticks) < kTestTime) && (!Button()); frames++)
  1428.         {
  1429.             if (gCollisionDetection)
  1430.             {
  1431.                 SWCollideSpriteLayer(spriteTestP->spriteWorldP, 
  1432.                     spriteTestP->globeSpriteLayerP, spriteTestP->globeSpriteLayerP);
  1433.             }
  1434.  
  1435.             SWProcessSpriteWorld( spriteTestP->spriteWorldP );
  1436.             SWAnimateSpriteWorld( spriteTestP->spriteWorldP );
  1437.         }
  1438.         
  1439.         seconds = ((TickCount() - ticks) / kTicksPerSecond);
  1440.     }
  1441. /*
  1442.     ProfilerSetStatus( false );
  1443.     ProfilerDump( "\pSWPPC Profile" );
  1444.     ProfilerTerm();
  1445. */
  1446.  
  1447.     SWSetFrameInterlacingMode( spriteTestP->spriteWorldP->workFrameP, false, false );
  1448.     SWSetFrameInterlacingMode( spriteTestP->spriteWorldP->windowFrameP, false, false );
  1449.  
  1450.         // restore things to default state
  1451.     RestoreFromTest( testWindowP, spriteTestP );
  1452.  
  1453.     if ( gInterlaced )
  1454.     {
  1455.         SWUpdateSpriteWorld( spriteTestP->spriteWorldP, true );
  1456.     
  1457.             // update windows in front (e.g. AppSwitcher), since interlacing erased them
  1458.         PaintBehind( (WindowPtr) spriteTestP->spriteWorldP->windowFrameP->framePort,
  1459.                   ((WindowPeek) (spriteTestP->spriteWorldP->windowFrameP))->strucRgn );
  1460.                   
  1461.         // note: should redraw ControlStrip here too, but no idea how to do that ?
  1462.     }
  1463.     
  1464.     if ( gClearBackground )
  1465.     {
  1466.         SWUpdateSpriteWorld( spriteTestP->spriteWorldP, true );
  1467.     }
  1468.  
  1469.     gLastTestFrames = frames;
  1470.     gLastTestSeconds = seconds;
  1471. }
  1472.  
  1473.  
  1474.  
  1475. /******************** RestoreFromTest ********************/
  1476. void RestoreFromTest(
  1477.     WindowPtr testWindowP,
  1478.     SpriteTestPtr spriteTestP)
  1479. {
  1480.     SpritePtr             curSpriteP;
  1481.     
  1482.     
  1483.         // restore things to default state
  1484.         
  1485.     curSpriteP = NULL;
  1486.  
  1487.     while ((curSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, curSpriteP)) != NULL)
  1488.     {
  1489.         (void)SWSetSpriteDrawProc(curSpriteP, SWStdSpriteDrawProc);
  1490.         
  1491.         if (curSpriteP != spriteTestP->titleSpriteP && curSpriteP != spriteTestP->twoSpriteP)
  1492.         {
  1493.             SWSetSpriteFrameTime(curSpriteP, kGlobeSpriteFrameTime);
  1494.             SWSetSpriteCollideProc(curSpriteP, RegionBounceCollideProc);
  1495.         }
  1496.     }
  1497.     
  1498.     (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, SWStdWorldDrawProc);
  1499.     (void)SWSetSpriteWorldScreenDrawProc(spriteTestP->spriteWorldP, SWStdWorldDrawProc);
  1500.     
  1501.     SWSetSpriteWorldMaxFPS( spriteTestP->spriteWorldP, 30 );
  1502.     
  1503.     ShowCursor();
  1504.     SWShowMenuBar(testWindowP);
  1505. }
  1506.  
  1507. #pragma mark -
  1508.  
  1509. /******************** DisplayPerformance ********************/
  1510. void DisplayPerformance(
  1511.     long frames,
  1512.     float seconds)
  1513. {
  1514.     Str255 framesString, secondsString, fpsString;
  1515.     float fps;
  1516.     
  1517.     NumToString(frames, framesString);
  1518.     NumToString(seconds, secondsString);
  1519.  
  1520.     fps = (seconds > 0.0) ? (float) frames / seconds : frames;
  1521.     
  1522.     NumToString(fps, fpsString);
  1523.     
  1524.     ParamText(framesString, secondsString, fpsString, "\p");
  1525.     NoteAlert(kPerformanceAlertID, NULL);
  1526. }
  1527.  
  1528.  
  1529. /******************** GlobeSpriteMoveProc ********************/
  1530. SW_FUNC void GlobeSpriteMoveProc(SpritePtr globeSpriteP)
  1531. {    
  1532.     SWOffsetSprite(globeSpriteP, globeSpriteP->horizMoveDelta, globeSpriteP->vertMoveDelta);
  1533.     (void)SWBounceSprite(globeSpriteP);
  1534. }
  1535.  
  1536. /******************** RectBounceCollideProc ********************/
  1537. SW_FUNC void RectBounceCollideProc(
  1538.     SpritePtr srcSpriteP,
  1539.     SpritePtr dstSpriteP,
  1540.     Rect* sectRect)
  1541. {    
  1542.  
  1543.         // If both sprites use the same collision routine (this one),ignore the second collision.
  1544.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  1545.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  1546.         (srcSpriteP > dstSpriteP)))
  1547.     {
  1548.         return;
  1549.     }
  1550.  
  1551.     if ( true )
  1552.     {
  1553.             // if a stationary sprite (the title), just bounce off it
  1554.         if ((dstSpriteP->horizMoveDelta == 0) && (dstSpriteP->vertMoveDelta == 0))
  1555.         {
  1556.             BounceGlobeOffTitle( dstSpriteP, srcSpriteP, sectRect );
  1557.         }
  1558.         else    
  1559.             // globe to globe collision; swap movement delta's
  1560.         {
  1561.             BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  1562.         }
  1563.     }
  1564. }
  1565. /******************** RLEBounceCollideProc ********************/
  1566. SW_FUNC void RLEBounceCollideProc(
  1567.     SpritePtr srcSpriteP,
  1568.     SpritePtr dstSpriteP,
  1569.     Rect* sectRect)
  1570. {    
  1571.  
  1572.         // If both sprites use the same collision routine (this one),ignore the second collision.
  1573.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  1574.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  1575.         (srcSpriteP > dstSpriteP)))
  1576.     {
  1577.         return;
  1578.     }
  1579.  
  1580.  
  1581.     if ( SWRLECollision(srcSpriteP, dstSpriteP) )
  1582.     {    
  1583.             // if a stationary sprite (the title), just bounce off it
  1584.         if ((dstSpriteP->horizMoveDelta == 0) && (dstSpriteP->vertMoveDelta == 0))
  1585.         {
  1586.             BounceGlobeOffTitle( dstSpriteP, srcSpriteP, sectRect );
  1587.         }
  1588.         else    
  1589.             // globe to globe collision; swap movement delta's
  1590.         {
  1591.             BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  1592.         }
  1593.     }
  1594. }
  1595.  
  1596. /******************** PixelBounceCollideProc ********************/
  1597. SW_FUNC void PixelBounceCollideProc(
  1598.     SpritePtr srcSpriteP,
  1599.     SpritePtr dstSpriteP,
  1600.     Rect* sectRect)
  1601. {    
  1602.  
  1603.         // If both sprites use the same collision routine (this one),ignore the second collision.
  1604.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  1605.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  1606.         (srcSpriteP > dstSpriteP)))
  1607.     {
  1608.         return;
  1609.     }
  1610.  
  1611.     if ( SWPixelCollision(srcSpriteP, dstSpriteP) )
  1612.     {
  1613.             // if a stationary sprite (the title), just bounce off it
  1614.         if ((dstSpriteP->horizMoveDelta == 0) && (dstSpriteP->vertMoveDelta == 0))
  1615.         {
  1616.             BounceGlobeOffTitle( dstSpriteP, srcSpriteP, sectRect );
  1617.         }
  1618.         else    
  1619.             // globe to globe collision; swap movement delta's
  1620.         {
  1621.             BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  1622.         }
  1623.     }
  1624. }
  1625.  
  1626.  
  1627. /******************** RegionBounceCollideProc ********************/
  1628. SW_FUNC void RegionBounceCollideProc(
  1629.     SpritePtr srcSpriteP,
  1630.     SpritePtr dstSpriteP,
  1631.     Rect* sectRect)
  1632. {    
  1633.  
  1634.         // If both sprites use the same collision routine (this one),ignore the second collision.
  1635.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  1636.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  1637.         (srcSpriteP > dstSpriteP)))
  1638.     {
  1639.         return;
  1640.     }
  1641.  
  1642.  
  1643.     if ( SWRegionCollision(srcSpriteP, dstSpriteP) )
  1644.     {
  1645.             // if a stationary sprite (the title), just bounce off it
  1646.         if ((dstSpriteP->horizMoveDelta == 0) && (dstSpriteP->vertMoveDelta == 0))
  1647.         {
  1648.             BounceGlobeOffTitle( dstSpriteP, srcSpriteP, sectRect );
  1649.         }
  1650.         else    
  1651.             // globe to globe collision; swap movement delta's
  1652.         {
  1653.             BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  1654.         }
  1655.     }
  1656. }
  1657.  
  1658.  
  1659. /******************** RadiusBounceCollideProc ********************/
  1660. SW_FUNC void RadiusBounceCollideProc(
  1661.     SpritePtr srcSpriteP,
  1662.     SpritePtr dstSpriteP,
  1663.     Rect* sectRect)
  1664. {
  1665.      #pragma unused(sectRect)
  1666.  
  1667.         // If both sprites use the same collision routine (this one),ignore the second collision.
  1668.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  1669.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  1670.         (srcSpriteP > dstSpriteP)))
  1671.         return;
  1672.  
  1673.         // ignore collision with title sprite
  1674.     if ( (srcSpriteP->destFrameRect.right-SWGetSpriteHorizLoc(srcSpriteP) !=
  1675.          srcSpriteP->destFrameRect.bottom-SWGetSpriteVertLoc(srcSpriteP)) ||
  1676.          (dstSpriteP->destFrameRect.right-dstSpriteP->destFrameRect.left !=
  1677.          dstSpriteP->destFrameRect.bottom-dstSpriteP->destFrameRect.top))
  1678.         return;
  1679.  
  1680.     if ( SWRadiusCollision( srcSpriteP, dstSpriteP ) )
  1681.     {
  1682.         BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  1683.     }
  1684. }
  1685.  
  1686.  
  1687. /******************** BounceGlobeOffGlobe ********************/
  1688. void BounceGlobeOffGlobe(
  1689.     SpritePtr srcSpriteP,
  1690.     SpritePtr dstSpriteP )
  1691. {
  1692.     short            tempDelta;
  1693.     short            nextHorizDistA, nextVertDistA,
  1694.                     nextHorizDistB, nextVertDistB;
  1695.  
  1696.     
  1697.         // reverse spins.
  1698.     srcSpriteP->frameAdvance = -srcSpriteP->frameAdvance;
  1699.     dstSpriteP->frameAdvance = -dstSpriteP->frameAdvance;
  1700.  
  1701.         // Calculate what the distance between sprites will be if we don't switch deltas
  1702.     nextHorizDistA = SWGetSpriteHorizLoc(srcSpriteP) + srcSpriteP->horizMoveDelta - 
  1703.                 (dstSpriteP->destFrameRect.left + dstSpriteP->horizMoveDelta);
  1704.     if (nextHorizDistA < 0)
  1705.         nextHorizDistA = -nextHorizDistA;
  1706.     
  1707.     nextVertDistA = SWGetSpriteVertLoc(srcSpriteP) + srcSpriteP->vertMoveDelta - 
  1708.                 (dstSpriteP->destFrameRect.top + dstSpriteP->vertMoveDelta);
  1709.     if (nextVertDistA < 0)
  1710.         nextVertDistA = -nextVertDistA;
  1711.     
  1712.         // Calculate what the distance between sprites will be if we do switch deltas
  1713.     nextHorizDistB = SWGetSpriteHorizLoc(srcSpriteP) + dstSpriteP->horizMoveDelta - 
  1714.                 (dstSpriteP->destFrameRect.left + srcSpriteP->horizMoveDelta);
  1715.     if (nextHorizDistB < 0)
  1716.         nextHorizDistB = -nextHorizDistB;
  1717.     
  1718.     nextVertDistB = SWGetSpriteVertLoc(srcSpriteP) + dstSpriteP->vertMoveDelta - 
  1719.                 (dstSpriteP->destFrameRect.top + srcSpriteP->vertMoveDelta);
  1720.     if (nextVertDistB < 0)
  1721.         nextVertDistB = -nextVertDistB;
  1722.     
  1723.     
  1724.         // Will swapping the horizontal deltas move the sprites farther apart?
  1725.     if (nextHorizDistB > nextHorizDistA)
  1726.     {
  1727.             // swap horizontal deltas
  1728.         tempDelta = srcSpriteP->horizMoveDelta;
  1729.         srcSpriteP->horizMoveDelta = dstSpriteP->horizMoveDelta;
  1730.         dstSpriteP->horizMoveDelta = tempDelta;
  1731.     }
  1732.     
  1733.         // Will swapping the vertical deltas move the sprites farther apart?
  1734.     if (nextVertDistB > nextVertDistA)
  1735.     {
  1736.             // swap vertical deltas
  1737.         tempDelta = srcSpriteP->vertMoveDelta;
  1738.         srcSpriteP->vertMoveDelta = dstSpriteP->vertMoveDelta;
  1739.         dstSpriteP->vertMoveDelta = tempDelta;
  1740.     }
  1741. }
  1742.  
  1743.  
  1744.  /******************** BounceGlobeOffTitle ********************/
  1745. void BounceGlobeOffTitle(
  1746.     SpritePtr titleSpriteP,
  1747.     SpritePtr globeSpriteP,
  1748.     Rect* sectRect )
  1749. {
  1750.     short        absHorizDelta,
  1751.                 absVertDelta;
  1752.                 
  1753.     absHorizDelta = globeSpriteP->horizMoveDelta;
  1754.     if ( absHorizDelta < 0 )
  1755.         absHorizDelta = -absHorizDelta;
  1756.     absVertDelta = globeSpriteP->vertMoveDelta;
  1757.     if ( absVertDelta < 0 )
  1758.         absVertDelta = -absVertDelta;
  1759.         
  1760.     // draw a picture and this test algorithm will become clear
  1761.     if ((sectRect->right - sectRect->left) < (sectRect->bottom - sectRect->top) )
  1762.     {
  1763.             // Hit left or right side
  1764.         if ( sectRect->left <= titleSpriteP->destFrameRect.left )
  1765.             // hit on left side
  1766.             globeSpriteP->horizMoveDelta = -absHorizDelta;
  1767.         else
  1768.             // hit on right side
  1769.             globeSpriteP->horizMoveDelta = absHorizDelta;
  1770.     }
  1771.     else
  1772.     {
  1773.             // Hit top or bottom
  1774.         if ( sectRect->top <= titleSpriteP->destFrameRect.top )
  1775.             // hit on top
  1776.             globeSpriteP->vertMoveDelta = -absVertDelta;
  1777.         else
  1778.             // hit on bottom
  1779.             globeSpriteP->vertMoveDelta = absVertDelta;
  1780.     }
  1781. }
  1782.